package com.xyzh.stj.web.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xyzh.stj.web.dto.right.QueryRightDTO;
import com.xyzh.stj.web.entity.*;
import com.xyzh.stj.web.dao.RightMapper;
import com.xyzh.stj.web.service.*;
import com.xyzh.stj.web.vo.right.MenuRight;
import com.xyzh.application.base.service.BasicServiceImpl;
import com.xyzh.application.base.vo.AuthorUser;
import com.xyzh.application.common.util.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 权限表 服务实现类
 * </p>
 *
 * @author @JZB
 * @since 2023-10-29
 */
@Service
public class RightServiceImpl extends BasicServiceImpl<RightMapper, RightEntity> implements RightService {

    @Autowired
    private OrganizationService organizationService;


    @Autowired
    private RoleService roleService;

    @Value("#{applicationProperies.info.adminCode}")
    private String sysAdmin;


    @Override
    public List<RightEntity> getRightsByRoles(List<RoleEntity> roles) {
        if (CollUtil.isEmpty(roles)) {
            return new ArrayList<RightEntity>();
        }
        return this.getBaseMapper().getRightsByRoles(roles);
    }


    @Override
    public List<MenuRight> getRightsByRoleId(String roleid) {
        if (StrUtil.isEmpty(roleid)) {
            return new ArrayList<MenuRight>();
        }
        List<RightEntity> rightEntities = this.getBaseMapper().getRightsByRoleid(roleid);
        return getChildMenu("0", rightEntities);
    }


    @Override
    public List<RightEntity> getRightsByOrganizations(List<OrganizationEntity> organizationEntities) {
        if (CollUtil.isEmpty(organizationEntities)) {
            return new ArrayList<RightEntity>();
        }
        List<String> orgids = organizationService.getSubOrgidsByParent(organizationEntities);
        return this.getBaseMapper().getRightsByOrgs(orgids);
    }


    @Override
    public List<MenuRight> getRightsByOrganizationId(String orgid) {
        if (StrUtil.isEmpty(orgid)) {
            return new ArrayList<MenuRight>();
        }
        List<RightEntity> rightEntities = this.getBaseMapper().getRightsByOrgid(orgid);
        return getChildMenu("0", rightEntities);
    }

    @Override
    public List<MenuRight> getRightsByUser(List<RoleEntity> roles, List<OrganizationEntity> organizationEntities) {

        List<RightEntity> rights = new ArrayList<>();
        AuthorUser authorUser = SecurityUtils.getAuthorUser();
        if (sysAdmin.equals(authorUser.getUsername())) {
            rights = this.list();
        } else {
            List<RightEntity> rightsByRoles = new ArrayList<>();
            if (CollUtil.isNotEmpty(roles)) {
                rightsByRoles = this.getRightsByRoles(roles);
            }
            List<RightEntity> rightsByOrgs = new ArrayList<>();
            if (CollUtil.isNotEmpty(organizationEntities)) {
                rightsByOrgs = this.getRightsByOrganizations(organizationEntities);
            }

            if (CollUtil.isNotEmpty(rightsByOrgs)) {
                rightsByRoles.addAll(rightsByOrgs);
            }
            rights = rightsByRoles.stream().distinct().sorted(Comparator.comparing(RightEntity::getSortkey)).collect(Collectors.toList());
        }
        List<MenuRight> menus = getChildMenu("0", rights);
        return menus;
    }


    @Override
    public List<MenuRight> getRightListByUser(QueryRightDTO queryRightDTO) {
        AuthorUser user = SecurityUtils.getAuthorUser();
        List<RightEntity> rights=new ArrayList<>();
        if (sysAdmin.equals(user.getUsername())) {
            LambdaQueryWrapper<RightEntity> queryWrapper=new LambdaQueryWrapper<>();
            queryWrapper.eq(StrUtil.isNotEmpty(queryRightDTO.getApplicationId()),RightEntity::getApplicationId,queryRightDTO.getApplicationId());
            queryWrapper.eq(StrUtil.isNotEmpty(queryRightDTO.getStatus()),RightEntity::getStatus,queryRightDTO.getStatus());
            queryWrapper.like(StrUtil.isNotEmpty(queryRightDTO.getName()),RightEntity::getName,queryRightDTO.getName());
            rights=  this.list(queryWrapper);
        } else {
            List<RoleEntity> roles = roleService.getRoleByUserid(user.getId());
            List<RightEntity> roleRights = new ArrayList<>();
            List<OrganizationEntity> organizationEntities = organizationService.getOrganizations(user.getId());
            List<String> orgs = organizationService.getSubOrgidsByParent(organizationEntities);
            roleRights = this.getBaseMapper().queryRightByRoles(roles, queryRightDTO);
            List<RightEntity> organizationRights = this.getBaseMapper().queryRightsByOrgs(orgs,queryRightDTO);
            if (CollUtil.isNotEmpty(organizationRights)) {
                roleRights.addAll(organizationRights);
            }
            rights= roleRights.stream().distinct().sorted(Comparator.comparing(RightEntity::getSortkey)).collect(Collectors.toList());
        }
       return ListTotree(rights);

    }


    @Override
    public List<MenuRight> getAllRight(RightEntity rightEntity) {
        List<RightEntity> rightEntities = this.list(rightEntity);
        Collections.sort(rightEntities, Comparator.comparing(RightEntity::getSortkey));
        return getChildMenu("0", rightEntities);
    }

    /**
     * 组装树，根节点为 ”0“
     * @param pid
     * @param rights
     * @return
     */
    private  List<MenuRight> getChildMenu(String pid, List<RightEntity> rights) {
        List<MenuRight> menuRights = new ArrayList<>();
        for (RightEntity right : rights) {
            if (pid.equals(right.getParentId())) {//判断传入的父id是否等于自身的，如果是，就说明自己是子节点
                MenuRight menu = new MenuRight();
                BeanUtils.copyProperties(right, menu);
                menuRights.add(menu);
            }
        }
        for (MenuRight map : menuRights) {//遍历子节点，继续递归判断每个子节点是否还含有子节点
            List<MenuRight> childList = getChildMenu(map.getId(), rights);
            map.setChildren(childList);
        }
        return menuRights;
    }

    /**
     * list转树，没有父节点放在更节点
     * @param rights
     * @return
     */
    private List<MenuRight> ListTotree(List<RightEntity> rights){
        Map<String , List<RightEntity>> groupRights=rights.stream().collect(Collectors.groupingBy(RightEntity::getParentId));
       List<MenuRight> menuRights=new ArrayList<>();
        rights.stream().forEach(d->{
            //判断有没有父级
         List<RightEntity>Parents=   rights.stream().filter(t->t.getId().equals(d.getParentId())).collect(Collectors.toList());
         if(CollUtil.isEmpty(Parents)){
             MenuRight menuRight=new MenuRight();
             BeanUtils.copyProperties(d,menuRight);
             getAllChildren(groupRights,menuRight);
             menuRights.add(menuRight);
         }
        });
        return menuRights;
    }
    private void getAllChildren(Map<String,List<RightEntity>>map,MenuRight rootMenu){
        List<RightEntity> childRights=map.get(rootMenu.getId());
        List<MenuRight> childMenus=new ArrayList<>();
        if(CollUtil.isNotEmpty(childRights)){
            childRights.stream().forEach(d->{
                MenuRight menuRight=new MenuRight();
                BeanUtils.copyProperties(d,menuRight);
                childMenus.add(menuRight);
                getAllChildren(map,menuRight);
            });
        }
        rootMenu.setChildren(childMenus);
    }



    @Override
    public boolean saveEntity(RightEntity rightEntity) {
        if (ObjectUtil.isEmpty(rightEntity.getSortkey()) || rightEntity.getSortkey() == 0) {
            rightEntity.setSortkey(this.getBaseMapper().selectSortKey() + 1);
        }
        return super.saveEntity(rightEntity);
    }



}
